package com.mingyuean.demo.mybatis.mapping;

import com.mingyuean.demo.mybatis.session.Configuration;

import java.util.Map;

/**
 * @author MingYueAn
 * <p>  映射配置文件：存放mapper.xml解析内容
 * <p>  MappedStatement类，表示一个映射语句的详细信息
 * <p>  2023/3/17 1:35
 * @version: 1.0
 */
public class MappedStatement {

    /**
     * Configuration对象，表示该映射语句所属的MyBatis配置
     */
    private Configuration configuration;
    /**
     * 唯一标识 id:namespace.id
     * 映射语句的ID，可以通过它在Configuration对象中查找该映射语句
     */
    private String id;
    /**
     * 映射语句的类型，包括INSERT、UPDATE、DELETE、SELECT四种
     */
    private SqlCommandType sqlCommandType;
    /**
     * 绑定的sql
     */
    private BoundSql boundSql;

    MappedStatement() {
        // 禁用构造器
    }

    /**
     * 建造者
     * <p> 建造者模式是一种对象创建型模式，它将复杂对象的创建过程分解为多个简单的步骤，以便于对不同步骤的需求进行灵活组合。同时，建造者模式使得相同的构建过程可以创建不同的表示，也就是说通过建造者模式可以创建出具有不同属性的对象。
     * <p> MappedStatement类是映射语句的详细信息类，而Builder类则是一个构建器，用于构建MappedStatement对象。
     */
    public static class Builder {
        // MappedStatement对象，用于保存正在构建的映射语句的详细信息
        private final MappedStatement mappedStatement = new MappedStatement();

        /**
         * 构造方法，用于初始化MappedStatement的各个属性
         *
         * @param configuration  Configuration对象，表示该映射语句所属的MyBatis配置
         * @param id             映射语句的ID，由namespace+id组成，可以通过它在Configuration对象中查找该映射语句
         * @param sqlCommandType 映射语句的类型，包括INSERT、UPDATE、DELETE、SELECT四种
         * @param resultType     映射语句对应的参数类型的全限定类名
         * @param parameterType  映射语句执行后返回的结果类型的全限定类名
         * @param parameterMap   用于标识动态SQL中的某个参数占位符的位置及其对应的属性名
         * @param sql            映射语句的SQL语句
         */
        public Builder(
                Configuration configuration,
                String id,
                SqlCommandType sqlCommandType,
                BoundSql boundSql
        ) {
            mappedStatement.configuration = configuration;
            mappedStatement.id = id;
            mappedStatement.sqlCommandType = sqlCommandType;
            mappedStatement.boundSql=boundSql;
        }

        /**
         * 构建MappedStatement对象，并进行必要的校验
         *
         * @return 构建完成的MappedStatement对象
         */
        public MappedStatement build() {
            // 断言校验，如果MappedStatement对象的configuration属性或id属性为null，
            // 则抛出AssertionError异常
            assert mappedStatement.configuration != null;
            assert mappedStatement.id != null;
            return mappedStatement;
        }
    }

    public Configuration getConfiguration() {
        return configuration;
    }

    public String getId() {
        return id;
    }

    public SqlCommandType getSqlCommandType() {
        return sqlCommandType;
    }

    public BoundSql getBoundSql() {
        return boundSql;
    }
}
